package org.herrdommel.wakemeup.app;

import org.herrdommel.preference.MultiSelectListPreference;
import org.herrdommel.preference.TimePickerPreference;
import org.herrdommel.wakemeup.R;
import org.herrdommel.wakemeup.WakeMeUpApplication;
import org.herrdommel.wakemeup.control.AlarmController;
import org.herrdommel.wakemeup.model.Alarm;
import org.herrdommel.wakemeup.util.DialogFactory;

import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.text.format.DateFormat;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

public class AlarmEditor extends PreferenceActivity implements OnSharedPreferenceChangeListener {

	// static key values for preferences
	private static final Context staticContext = WakeMeUpApplication.getWakeMeUpContext();
	private static final String KEY_NAME = staticContext.getString(R.string.prefKeyName);
	private static final String KEY_TIME = staticContext.getString(R.string.prefKeyTime);
	private static final String KEY_ISACTIVE = staticContext.getString(R.string.prefKeyIsActive);
	private static final String KEY_NEEDSCONFIRM = staticContext.getString(R.string.prefKeyNeedsConfirm);
	private static final String KEY_ALERTLOWBAT = staticContext.getString(R.string.prefKeyAlertLowBat);

	// UI elements
	private EditTextPreference edtPrefName;
	private TimePickerPreference tpPrefTime;
	private CheckBoxPreference chkPrefIsActive;
	private CheckBoxPreference chkPrefNeedsConfirm;
	private CheckBoxPreference chkPrefAlertLowBat;

	// helper
	private Alarm alarm;
	private AlarmController controller;

	@Override
	protected void onCreate(final Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// Load the XML preferences file
		addPreferencesFromResource(R.xml.alarm_settings);

		// Get a reference to each preference
		edtPrefName = (EditTextPreference) getPreferenceScreen().findPreference(KEY_NAME);
		tpPrefTime = (TimePickerPreference) getPreferenceScreen().findPreference(KEY_TIME);
		chkPrefIsActive = (CheckBoxPreference) getPreferenceScreen().findPreference(KEY_ISACTIVE);
		chkPrefNeedsConfirm = (CheckBoxPreference) getPreferenceScreen().findPreference(KEY_NEEDSCONFIRM);
		chkPrefAlertLowBat = (CheckBoxPreference) getPreferenceScreen().findPreference(KEY_ALERTLOWBAT);

		// Create new controller
		controller = new AlarmController(this);
		// Retrieve alarm id from intent
		final long alarmId = getIntent().getLongExtra("alarmid", -1);
		alarm = controller.getAlarmById(alarmId);
		// Initialize the preference values
		initSummary();
	}

	@Override
	protected void onResume() {
		super.onResume();
		// Register onSharedPreferenceChangeListener
		getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
	}

	@Override
	protected void onPause() {
		super.onPause();
		// Unregister onSharedPreferenceChangeListener
		getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
	}

	@Override
	public void onSharedPreferenceChanged(final SharedPreferences sharedPreferences, final String key) {
		updatePrefSummary(key);
	}

	@Override
	public void onBackPressed() {
		super.onBackPressed();
		controller.handleAlarmManipulation(alarm);
	}

	@Override
	public boolean onCreateOptionsMenu(final Menu menu) {
		final MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.menu_alarm_editor, menu);
		if (alarm != null && alarm.getId() == -1) {
			final MenuItem deleteAlarm = menu.findItem(R.id.mnuDeleteAlarm);
			deleteAlarm.setEnabled(false);
		}
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(final MenuItem item) {
		switch (item.getItemId()) {
			case R.id.mnuSaveAlarm :
				controller.handleAlarmManipulation(alarm);
				finish();
				return true;
			case R.id.mnuDeleteAlarm :
				controller.handleAlarmDeletion(alarm.getId());
				finish();
				return true;
			case R.id.mnuSettings :
				final Intent settingsIntent = new Intent(this, ApplicationSettings.class);
				startActivity(settingsIntent);
				return true;
			case R.id.mnuAbout :
				showDialog(DialogFactory.DIALOG_ABOUT);
				return true;
			default :
				return super.onOptionsItemSelected(item);
		}
	}

	@Override
	protected Dialog onCreateDialog(final int id) {
		final Dialog dialog = DialogFactory.createDialog(id, this);
		if (dialog != null) {
			return dialog;
		} else {
			return super.onCreateDialog(id);
		}
	}

	/** Initializes all preference views */
	private void initSummary() {
		// Every preference should be initialized here
		edtPrefName.setSummary(String.valueOf(alarm.getName()));
		edtPrefName.setText(String.valueOf(alarm.getName()));
		tpPrefTime.setSummary(DateFormat.getTimeFormat(this).format(alarm.getAlarmTimeAsDate()));
		tpPrefTime.setTime(alarm.getAlarmTimeAsDate());
		chkPrefIsActive.setSummary(getActiveStateString(alarm.isActive()));
		chkPrefIsActive.setChecked(alarm.isActive());
		chkPrefNeedsConfirm.setSummary(getActiveStateString(alarm.isNeedsConfirmation()));
		chkPrefNeedsConfirm.setChecked(alarm.isNeedsConfirmation());
		chkPrefAlertLowBat.setSummary(getActiveStateString(alarm.isAlertOnLowBattery()));
		chkPrefAlertLowBat.setChecked(alarm.isAlertOnLowBattery());
	}

	/**
	 * Updates the summary of a preference and the private member {@code alarm}
	 * @param key the preferences key
	 */
	private void updatePrefSummary(final String key) {
		final Preference p = findPreference(key);
		if (p instanceof EditTextPreference) {
			final EditTextPreference editTextPref = (EditTextPreference) p;
			p.setSummary(editTextPref.getText());
			if (key.equals(KEY_NAME)) {
				alarm.setName(editTextPref.getText());
			}
		} else if (p instanceof TimePickerPreference) {
			final TimePickerPreference timePickerPref = (TimePickerPreference) p;
			final String timeString = timePickerPref.getTime();
			p.setSummary(timeString);
			if (key.equals(KEY_TIME)) {
				alarm.setAlarmTime(timeString);
			}
		} else if (p instanceof CheckBoxPreference) {
			final CheckBoxPreference chkBoxPref = (CheckBoxPreference) p;
			final boolean isChecked = chkBoxPref.isChecked();
			p.setSummary(getActiveStateString(isChecked));
			if (key.equals(KEY_ISACTIVE)) {
				alarm.setActive(isChecked);
			} else if (key.equals(KEY_NEEDSCONFIRM)) {
				alarm.setNeedsConfirmation(isChecked);
			} else if (key.equals(KEY_ALERTLOWBAT)) {
				alarm.setAlertOnLowBattery(isChecked);
			}
		} else if (p instanceof MultiSelectListPreference) {
			final MultiSelectListPreference multiListPref = (MultiSelectListPreference) p;
			p.setSummary(multiListPref.getEntry());
			// TODO: update alarm
		}
	}

	/**
	 * According to the {@code state} it returns a string. In case of {@code state = true} it returns the localized
	 * equivalent of activated or deactivated otherwise.
	 * @param state the state
	 * @return the localized equivalent of activated if {@code state = true}, localized equivalent of deactivated
	 *         otherwise
	 */
	private String getActiveStateString(final boolean state) {
		if (state) {
			return getString(R.string.activated);
		} else {
			return getString(R.string.deactivated);
		}
	}
}
